programming4us
           
 
 
Programming

iPhone 3D Programming : Vertices and Touch Points - Reading the Touchscreen

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
11/23/2010 11:35:59 AM
In this article, I’ll introduce the touchscreen API by walking through a modification of HelloCone that makes the cone point toward the user’s finger. You’ll need to change the name of the app from HelloCone to TouchCone, since the user now touches the cone instead of merely greeting it. To do this, make a copy of the project folder in Finder, and name the new folder TouchCone. Next, open the Xcode project (it will still have the old name), and select ProjectRename. Change the name to TouchCone, and click Rename.

Apple’s multitouch API is actually much richer than what we need to expose through our IRenderingEngine interface. For example, Apple’s API supports the concept of cancellation, which is useful to robustly handle situations such as an interruption from a phone call. For our purposes, a simplified interface to the rendering engine is sufficient. In fact, we don’t even need to accept multiple touches simultaneously; the touch handler methods can simply take a single coordinate.

For starters, let’s add three methods to IRenderingEngine for “finger up” (the end of a touch), “finger down” (the beginning of a touch), and “finger move.” Coordinates are passed to these methods using the ivec2 type from the vector library . Example 1 shows the modifications to IRenderingEngine.hpp (new lines are in bold).

Example 1. IRenderingEngine interface for TouchCone
#include "Vector.hpp"

...

struct IRenderingEngine {
virtual void Initialize(int width, int height) = 0;
virtual void Render() const = 0;
virtual void UpdateAnimation(float timeStep) = 0;
virtual void OnRotate(DeviceOrientation newOrientation) = 0;
virtual void OnFingerUp(ivec2 location) = 0;
virtual void OnFingerDown(ivec2 location) = 0;
virtual void OnFingerMove(ivec2 oldLocation, ivec2 newLocation) = 0;
virtual ~IRenderingEngine() {}
};

The iPhone notifies your view of touch events by calling methods on your UIView class, which you can then override. The three methods we’re interested in overriding are touchesBegan, touchedEnded, and touchesMoved. Open GLView.mm, and implement these methods by simply passing on the coordinates to the rendering engine:

- (void) touchesBegan: (NSSet*) touches withEvent: (UIEvent*) event
{
UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInView: self];
m_renderingEngine->OnFingerDown(ivec2(location.x, location.y));
}

- (void) touchesEnded: (NSSet*) touches withEvent: (UIEvent*) event
{
UITouch* touch = [touches anyObject];
CGPoint location = [touch locationInView: self];
m_renderingEngine->OnFingerUp(ivec2(location.x, location.y));
}

- (void) touchesMoved: (NSSet*) touches withEvent: (UIEvent*) event
{
UITouch* touch = [touches anyObject];
CGPoint previous = [touch previousLocationInView: self];
CGPoint current = [touch locationInView: self];
m_renderingEngine->OnFingerMove(ivec2(previous.x, previous.y),
ivec2(current.x, current.y));
}

The RenderingEngine1 implementation (Example 2) is similar to HelloCone, but the OnRotate and UpdateAnimation methods become empty. Example 2 also notifies the user that the cone is active by using glScalef to enlarge the geometry while the user is touching the screen. New and changed lines in the class declaration are shown in bold. Note that we’re removing the Animation structure.

Example 2. RenderingEngine1.cpp in TouchCone
class RenderingEngine1 : public IRenderingEngine {
public:
RenderingEngine1();
void Initialize(int width, int height);
void Render() const;
void UpdateAnimation(float timeStep) {}
void OnRotate(DeviceOrientation newOrientation) {}
void OnFingerUp(ivec2 location);
void OnFingerDown(ivec2 location);
void OnFingerMove(ivec2 oldLocation, ivec2 newLocation);
private:
vector<Vertex> m_cone;
vector<Vertex> m_disk;
GLfloat m_rotationAngle;
GLfloat m_scale;
ivec2 m_pivotPoint;
GLuint m_framebuffer;
GLuint m_colorRenderbuffer;
GLuint m_depthRenderbuffer;
};

RenderingEngine1::RenderingEngine1() : m_rotationAngle(0), m_scale(1)
{
glGenRenderbuffersOES(1, &m_colorRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_colorRenderbuffer);
}

void RenderingEngine1::Initialize(int width, int height)
{
m_pivotPoint = ivec2(width / 2, height / 2);

...
}

void RenderingEngine1::Render() const
{
glClearColor(0.5f, 0.5f, 0.5f, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_COLOR_ARRAY);

glRotatef(m_rotationAngle, 0, 0, 1); // Replaces call to rotation()
glScalef(m_scale, m_scale, m_scale); // Replaces call to glMultMatrixf()

// Draw the cone.
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &m_cone[0].Position.x);
glColorPointer(4, GL_FLOAT, sizeof(Vertex), &m_cone[0].Color.x);
glDrawArrays(GL_TRIANGLE_STRIP, 0, m_cone.size());

// Draw the disk that caps off the base of the cone.
glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &m_disk[0].Position.x);
glColorPointer(4, GL_FLOAT, sizeof(Vertex), &m_disk[0].Color.x);
glDrawArrays(GL_TRIANGLE_FAN, 0, m_disk.size());

glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);

glPopMatrix();
}

void RenderingEngine1::OnFingerUp(ivec2 location)
{
m_scale = 1.0f;
}

void RenderingEngine1::OnFingerDown(ivec2 location)
{
m_scale = 1.5f;
OnFingerMove(location, location);
}

void RenderingEngine1::OnFingerMove(ivec2 previous, ivec2 location)
{
vec2 direction = vec2(location - m_pivotPoint).Normalized();

// Flip the y-axis because pixel coords increase toward the bottom.
direction.y = -direction.y;

m_rotationAngle = std::acos(direction.y) * 180.0f / 3.14159f;
if (direction.x > 0)
m_rotationAngle = -m_rotationAngle;
}


The only bit of code in Example 2 that might need some extra explanation is the OnFingerMove method; it uses some trigonometric trickery to compute the angle of rotation. The best way to explain this is with a diagram, as shown in Figure 1. Recall from high-school trig that the cosine is “adjacent over hypotenuse.” We normalized the direction vector, so we know the hypotenuse length is exactly one. Since cos(θ)=y, then acos(y)=θ. If the direction vector points toward the right of the screen, then the rotation angle should be reversed, as illustrated on the right. This is because rotation angles are counterclockwise in our coordinate system.

Figure 1. Trigonometry in OnFingerMove


Note that OnFingerMove flips the y-axis. The pixel-space coordinates that come from UIView have the origin at the upper-left corner of the screen, with +Y pointing downward, while OpenGL (and mathematicians) prefer to have the origin at the center, with +Y pointing upward.

That’s it! The 1.1 ES version of the Touch Cone app is now functionally complete. If you want to compile and run at this point, don’t forget to turn on the ForceES1GLView.mm. switch at the top of

Let’s move on to the ES 2.0 renderer. Open RenderingEngine2.cpp, and make the changes shown in bold in Example 3. Most of these changes are carried over from our ES 1.1 changes, with some minor differences in the Render method.

Example 3. RenderingEngine2.cpp in TouchCone
class RenderingEngine2 : public IRenderingEngine {
public:
RenderingEngine2();
void Initialize(int width, int height);
void Render() const;
void UpdateAnimation(float timeStep) {}
void OnRotate(DeviceOrientation newOrientation) {}
void OnFingerUp(ivec2 location);
void OnFingerDown(ivec2 location);
void OnFingerMove(ivec2 oldLocation, ivec2 newLocation);
private:

...

GLfloat m_rotationAngle;
GLfloat m_scale;
ivec2 m_pivotPoint;
};

RenderingEngine2::RenderingEngine2() : m_rotationAngle(0), m_scale(1)
{
glGenRenderbuffersOES(1, &m_colorRenderbuffer);
glBindRenderbufferOES(GL_RENDERBUFFER_OES, m_colorRenderbuffer);
}

void RenderingEngine2::Initialize(int width, int height)
{
m_pivotPoint = ivec2(width / 2, height / 2);

...
}

void RenderingEngine2::Render() const
{
GLuint positionSlot = glGetAttribLocation(m_simpleProgram,
"Position");
GLuint colorSlot = glGetAttribLocation(m_simpleProgram,
"SourceColor");

glClearColor(0.5f, 0.5f, 0.5f, 1);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

glEnableVertexAttribArray(positionSlot);
glEnableVertexAttribArray(colorSlot);

mat4 rotation = mat4::Rotate(m_rotationAngle);
mat4 scale = mat4::Scale(m_scale);
mat4 translation = mat4::Translate(0, 0, -7);

// Set the model-view matrix.
GLint modelviewUniform = glGetUniformLocation(m_simpleProgram,
"Modelview");
mat4 modelviewMatrix = scale * rotation * translation;
glUniformMatrix4fv(modelviewUniform, 1, 0, modelviewMatrix.Pointer());

// Draw the cone.
{
GLsizei stride = sizeof(Vertex);
const GLvoid* pCoords = &m_cone[0].Position.x;
const GLvoid* pColors = &m_cone[0].Color.x;
glVertexAttribPointer(positionSlot, 3, GL_FLOAT,
GL_FALSE, stride, pCoords);
glVertexAttribPointer(colorSlot, 4, GL_FLOAT,
GL_FALSE, stride, pColors);
glDrawArrays(GL_TRIANGLE_STRIP, 0, m_cone.size());
}

// Draw the disk that caps off the base of the cone.
{
GLsizei stride = sizeof(Vertex);
const GLvoid* pCoords = &m_disk[0].Position.x;
const GLvoid* pColors = &m_disk[0].Color.x;
glVertexAttribPointer(positionSlot, 3, GL_FLOAT,
GL_FALSE, stride, pCoords);
glVertexAttribPointer(colorSlot, 4, GL_FLOAT,
GL_FALSE, stride, pColors);
glDrawArrays(GL_TRIANGLE_FAN, 0, m_disk.size());
}

glDisableVertexAttribArray(positionSlot);
glDisableVertexAttribArray(colorSlot);
}

// See Example 3-2 for OnFingerUp, OnFingerDown, and OnFingerMove.
...


You can now turn off the ForceES1 switch in GLView.mm and build and run TouchCone on any Apple device. In the following sections, we’ll continue making improvements to the app, focusing on how to efficiently describe the cone geometry.

Other -----------------
- iPhone 3D Programming : HelloCone with Shaders
- Search Engine Basics : Country-Specific Search Engines
- Search Engine Basics : Vertical Search Engines
- Building Android Apps : Animation - Adding the Settings Panel
- Building Android Apps : Animation - Adding the New Entry Panel
- Building Android Apps : Animation - Adding the Date Panel
- Building Android Apps : Animation - Adding the Dates Panel
- Building Android Apps : Animation - Sliding Home
- Programming Windows Azure : Understanding the Value of Queues
- Programming Windows Azure : Table Operations - Deleting Tables, Deleting Entities
- Programming Windows Azure : Table Operations - Updating Entities
- Programming Windows Azure : Table Operations - Understanding Pagination
- Programming Windows Azure : Table Operations - Using Partitioning
- Programming Windows Azure : Table Operations - Querying Data
- Programming Windows Azure : Table Operations - Creating Entities
- Programming Windows Azure : Table Operations - Creating Tables
- iPad Development : Document Management (part 2)
- iPad Development : Document Management (part 1)
- iPad Development : The Split View Concept
- jQuery 1.3 : Developing plugins - Adding new shortcut methods
 
 
 
Top 10
 
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
programming4us programming4us